(defstruct (dll (:print-function print-dll)) 
  prev 
  next 
  data)

(defun dl-insert (x lst)
  (let ((dlx (make-dll :data x :next lst)))
    (if (dll-p lst)
      (setf (dll-prev lst) dlx))
    dlx))


(defun print-dll (lst stream depth)
  (declare (ignore depth))
  (format stream "#DL<~A>" (dl->list lst)))


(defun dl->list (lst)
  (if (dll-p lst)
    (cons (dll-data lst) (dl->list (dll-next lst)))
    nil))

(defun dl-list (&rest args)
  (reduce #'dl-insert args :from-end t :initial-value nil)) 

(defun dl-remove (lst)
  (if (dll-next lst)
       (setf (dll-prev (dll-next lst)) nil))
  (dll-next lst))
